#include "headers/Buffer.h"
#include "headers/Config.h"
#include "headers/Tracker.h"
#include "headers/Disco.h"

#include <time.h>
#include <stdio.h>

BufferPosition buf_data[CAPACIDADE_DO_BUFFER];
int buf_count = 0;
int count_LRU = 0;
int count_LRU_dirty = 0;

int LRU();

void    CriarBuffer() {
	/*Pagina p = temp.lerPagina();

	buf_data[vazio].pagina = p*/

}

void MostrarBuffer(){
	int i;
	for (i = 0; i < CAPACIDADE_DO_BUFFER; i++) {
		printf("Posicao no Buffer: %d\n", i);

		printf("GID: %d\n", buf_data[i].pagina.id);
		printf("Conteudo: %s\n", buf_data[i].pagina.conteudo);
		printf("------------------------------------------\n");
	}
}


Pagina* buff_LerPagina(int offset) {
	trac_HitDate(buf_data[offset].pagina.id); //Atualiza hit e data
	return &buf_data[offset].pagina;
}
void    buff_EscreverPagina(Pagina* p) {
	int offsetDeTroca;

	if(buf_count == CAPACIDADE_DO_BUFFER){ //Ou seja, buffer cheio.

		offsetDeTroca = LRU();
		count_LRU++;
		/*printf("Pagina escolhida pelo LRU: \n");
		printf("GID:      %d\n", buf_data[offsetDeTroca].pagina.id);
		printf("Conteudo: %s\n", buf_data[offsetDeTroca].pagina.conteudo);
		printf("Data:     %lu\n", trac_data[buf_data[offsetDeTroca].pagina.id].date);*/

		trac_ResetarPagina(buf_data[offsetDeTroca].pagina.id);//Reseta a pagina que vai sair.
		buf_data[offsetDeTroca].pagina = *p; //Salva a p�gina nova na posi��o livre do buffer.
		trac_AtualizarPagina(p->id, 'B', offsetDeTroca);//Atualiza a p�gina no Tracker

		/*printf("Nova pagina gravada no Buffer: \n");
		printf("GID:      %d\n", p->id);
		printf("Conteudo: %s\n", p->conteudo);
		printf("Data:     %lu\n", trac_data[p->id].date);*/

		//LRU, MRU e etc

	}else{ // se tem espaco livre pra inserir no buffer
		buf_data[buf_count].pagina = *p;
		trac_AtualizarPagina(p->id, 'B', buf_count);//Atualiza a p�gina no Tracker
		buf_count++;
	}
}

void buff_AlterarPagina(int pos){
	trac_data[buf_data[pos].pagina.id].alteracoes++;
	trac_data[buf_data[pos].pagina.id].hits++;
	trac_data[buf_data[pos].pagina.id].dirty=1;
}

int LRU(){
	unsigned long dateAux = trac_data[buf_data[0].pagina.id].date; //Para compara��o
	int i;
	int pos, offsetLRU;
	for (i = 0; i < CAPACIDADE_DO_BUFFER; i++) {
		pos = buf_data[i].pagina.id;

		if(dateAux >= trac_data[pos].date){
			dateAux = trac_data[pos].date;
			offsetLRU = i;
		}
	}

	// alteracao para contabilizar dirty pages
	if (trac_data[offsetLRU].dirty == 1) {
		count_LRU_dirty++;

		// gera escrita na mídia para simular o swap de página
		// disc_gravarPagina(&buf_data[offsetDeTroca].pagina);
		// disc_gravarPagina_LRU(&buf_data[offsetDeTroca].pagina);
		disc_gravarPagina_LRU(&buf_data[offsetLRU].pagina);

	}

	return offsetLRU;

}

void    ApagarBuffer() {

}

int writeToFile(){

}

